package com.westvalley.plugin.db;

import java.beans.PropertyVetoException;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import weaver.general.SecurityHelper;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.IDataSourceProvider;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.westvalley.common.kit.CastKit;
import com.westvalley.plugin.db.xml.Construct;
import com.westvalley.plugin.db.xml.InvokeFactory;
import com.westvalley.plugin.db.xml.ServicePoint;

public class OtherDataSource implements IDataSourceProvider{
	private static Map<String,String> driverClassMap;
	private String jdbcUrl;
	private String user;
	private String password;
	private String driverClass = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
	private int maxPoolSize = 100;
	private int minPoolSize = 10;
	private int initialPoolSize = 10;
	private int maxIdleTime = 20;
	private int acquireIncrement = 2;
	
	static{
		driverClassMap = new HashMap<String, String>();
		driverClassMap.put("sqlserver", "com.microsoft.sqlserver.jdbc.SQLServerDriver");
		driverClassMap.put("sqlserver2005", "com.microsoft.sqlserver.jdbc.SQLServerDriver");
		driverClassMap.put("sqlserver2008", "com.microsoft.sqlserver.jdbc.SQLServerDriver");
		driverClassMap.put("oracle", "oracle.jdbc.driver.OracleDriver");
		driverClassMap.put("mysql", "com.mysql.jdbc.Driver");
		driverClassMap.put("db2", "com.ibm.db2.jcc.DB2Driver");
		driverClassMap.put("sybase", "com.sybase.jdbc.SybDriver");
		driverClassMap.put("informix", "com.informix.jdbc.IfxDriver");
	}
	
	public OtherDataSource(String type,String datasourcename,String iscluster,String typename,String url,String host,String port,String dbname,String user,String password,String minconn,String maxconn,String iscode){
		initC3p0(type, datasourcename, iscluster, typename, url, host, port, dbname, user, password, minconn, maxconn, iscode);
	}
	
	public OtherDataSource(ServicePoint servicePoint){
		for(InvokeFactory invokeFactory : servicePoint.invokeFactorys){
			for(Construct construct : invokeFactory.constructs){
				initC3p0(construct.getType(), construct.getDataSourceName(), construct.getIsCluster(), construct.getTypeName(), construct.getUrl(), construct.getHost(), construct.getPort(), construct.getDbName(), construct.getUser(), construct.getPassWord(), construct.getMinConn(), construct.getMaxConn(), construct.getIsCode());
			}
		}
	}
	
	public OtherDataSource(Construct construct){
		initC3p0(construct.getType(), construct.getDataSourceName(), construct.getIsCluster(), construct.getTypeName(), construct.getUrl(), construct.getHost(), construct.getPort(), construct.getDbName(), construct.getUser(), construct.getPassWord(), construct.getMinConn(), construct.getMaxConn(), construct.getIsCode());
	}
	
	private void initC3p0(String type,String datasourcename,String iscluster,String typename,String url,String host,String port,String dbname,String user,String password,String minconn,String maxconn,String iscode){
		this.jdbcUrl = "2".equals(iscluster) ? url : "jdbc:sqlserver://"+host+":"+port+";DatabaseName="+dbname;
		this.user = "1".equals(iscode) ? SecurityHelper.decrypt(SecurityHelper.KEY, user) : user;
		this.password = "1".equals(iscode) ? SecurityHelper.decrypt(SecurityHelper.KEY, password) : password;
		this.driverClass = driverClassMap.get(type);
		this.maxPoolSize = StrKit.notBlank(maxconn) ? CastKit.cast(Integer.class, maxconn) : this.maxPoolSize;
		this.minPoolSize = StrKit.notBlank(minconn) ? CastKit.cast(Integer.class, minconn) : this.minPoolSize;
	}
	
	public DataSource getDataSource() {
		ComboPooledDataSource dataSource = new ComboPooledDataSource();
		dataSource.setJdbcUrl(jdbcUrl);
		dataSource.setUser(user);
		dataSource.setPassword(password);
		try {dataSource.setDriverClass(driverClass);}
		catch (PropertyVetoException e) {dataSource = null; throw new RuntimeException("C3p0Plugin start error.",e);} 
		dataSource.setMaxPoolSize(maxPoolSize);
		dataSource.setMinPoolSize(minPoolSize);
		dataSource.setInitialPoolSize(initialPoolSize);
		dataSource.setMaxIdleTime(maxIdleTime);
		dataSource.setAcquireIncrement(acquireIncrement);
		return dataSource;
	}
	
}
